package com.pactera.madp.cp.controller.sidebar.agent;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.common.log.annotation.SysLog;
import com.pactera.madp.common.security.util.SecurityUtils;
import com.pactera.madp.cp.api.entity.CorpEntity;
import com.pactera.madp.cp.api.entity.WorkAgentEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeEntity;
import com.pactera.madp.cp.api.vo.ApiRespVO;
import com.pactera.madp.cp.api.model.properties.ChatToolProperties;
import com.pactera.madp.cp.api.vo.JsSdkVo;
import com.pactera.madp.cp.common.util.JwtUtil;
import com.pactera.madp.cp.common.util.RSAUtils;
import com.pactera.madp.cp.common.util.RedisUtil;
import com.pactera.madp.cp.common.util.WxApiUtils;
import com.pactera.madp.cp.common.util.wm.ApiRespUtils;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.WorkEmployeeMapper;
import com.pactera.madp.cp.service.impl.AccountService;
import com.pactera.madp.cp.service.ICorpService;
import com.pactera.madp.cp.service.IWorkAgentService;
import com.pactera.madp.cp.service.StorageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: yangpengwei
 * @time: 2021/1/27 2:16 下午
 * @description 企业微信侧边栏应用域名校验
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/agent")
@Api(value = "agent", tags = "企业微信侧边栏应用域名校验--暂未修改")
public class AgentController {

    private ChatToolProperties chatToolProperties;
    private StorageService storageService;
    private IWorkAgentService workAgentService;
    private ICorpService corpService;
    private WorkEmployeeMapper workEmployeeMapper;

    @GetMapping("/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
        Resource file = storageService.loadAsResource(filename);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION,
                        "attachment; filename=\"" + file.getFilename() + "\"")
                .body(file);
    }

    @PostMapping("/txtverifyupload")
    @ResponseBody
    public ApiRespVO handleFileUpload(@RequestParam("file") MultipartFile file) {
        storageService.store(file);
        return ApiRespUtils.getApiRespOfOk("");
    }

    /**
     * @param agentId      应用 ID
     * @param isJsRedirect 是否跳转回本页面 0, 否; 1, 是
     * @param act          跳转回本页面时带的自定义参数，如客户标识，素材库标识
     */
    @GetMapping("/oauth")
    public ApiRespVO oauth(Integer agentId,@RequestParam(defaultValue = "0") String isJsRedirect,@RequestParam(defaultValue = "") String act) {
        if(agentId == null){
            throw new CheckedException("应用 ID 不能为空");
        }
        // 获取企业微信 id
        CorpEntity corpEntity = workAgentService.getCorp(agentId);
        String wxCorpId = corpEntity.getWxCorpId();

        String redirectUrl = chatToolProperties.getApiUrl() + "/oauth/callback"
                + "?agentId=" + agentId
                + "&isJsRedirect=" + isJsRedirect
                + "&act=" + act;

        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + wxCorpId +
                "&redirect_uri=" + redirectUrl +
                "&response_type=code" +
                "&scope=snsapi_base" +
                "&state=" +
                "#wechat_redirect";

        HashMap<String, String> map = new HashMap<>(1);
        map.put("url", url);
        return ApiRespUtils.getApiRespOfOk(map);
    }

    /**
     * @param agentId      应用 ID
     * @param isJsRedirect 是否跳转回本页面 0, 否; 1, 是
     * @param act          跳转回本页面时带的自定义参数，如客户标识，素材库标识
     * @param code         企业微信回调时返回值
     */
    @GetMapping("/oauth/callback")
    public void oauth(
            Integer agentId,
            @RequestParam(defaultValue = "0") String isJsRedirect,
            @RequestParam(defaultValue = "") String act,
            @RequestParam(defaultValue = "") String code,
            HttpServletResponse response
    ) throws IOException {
        if(agentId == null){
            throw new CheckedException("应用 ID 不能为空");
        }

        // 获取企业微信 id
        CorpEntity corpEntity = workAgentService.getCorp(agentId);

        // 根据 code 查询员工信息
        String wxUserId = WxApiUtils.requestWxUserIdApi(corpEntity.getCorpId(), agentId, code);
        WorkEmployeeEntity workEmployeeEntity = workEmployeeMapper.selectOne(
                new QueryWrapper<WorkEmployeeEntity>()
                        .eq("wx_user_id", wxUserId)
        );

        // 根据员工信息登录
        if (SecurityUtils.getUser().getId() == workEmployeeEntity.getLogUserId()) {
            throw new CheckedException("登录失败,用户不存在");
        }
        String token = JwtUtil.createJWT(36000000, SecurityUtils.getUser());
        RedisUtil.set("mc:user.token" + token, "1");
        AccountService.updateCorpIdAndEmployeeId(workEmployeeEntity.getLogUserId(), workEmployeeEntity.getCorpId(), workEmployeeEntity.getId());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("corpId", corpEntity.getCorpId());
        jsonObject.put("token", token);
        jsonObject.put("expire", 36000000);
        jsonObject.put("agentId", agentId);
        jsonObject.put("isJsRedirect", isJsRedirect);
        jsonObject.put("act", act);
        ApiRespVO apiRespVO = new ApiRespVO(200, "登录成功", jsonObject);
        String dataJson = JSON.toJSONString(apiRespVO);
        String data = RSAUtils.base64EncodeToString(dataJson.getBytes());
        // 微信回调, 需要重定向到前端页面
        String redirectUrl = chatToolProperties.getWebUrl() + "/codeAuth?callValues=" + data;
        response.sendRedirect(redirectUrl);
    }

    /**
     * 企业及应用签名
     * @param uriPath
     * @param agentId
     * @return
     */
    @GetMapping("/wxjssdk/config")
    @ApiOperation(value = "企业及应用签名")
    public R<JsSdkVo> wxJSConfig(
            @RequestParam(defaultValue = "") String uriPath,
            @RequestParam(defaultValue = "0") Integer agentId
    ) {
        Integer corpId = CorpContextHolder.getCorpId();
        if(corpId == null){
            throw new CheckedException("企业 ID 无效");
        }

        String ticket = "";
        if (agentId < 0) {
            // 分享金融小店时，小店应用id前端无法获取，所以agentid传参小于0时，固定取小店agentid
            WorkAgentEntity wae =  workAgentService.getAgentByHomeName("#/financialShop");
            // 重置agentId
            agentId = Integer.valueOf(wae.getWxAgentId());
            ticket = WxApiUtils.getJsapiTicketOfApp(corpId, agentId);
        } else if (agentId > 0) {
            // 应用 ticket
            ticket = WxApiUtils.getJsapiTicketOfApp(corpId, agentId);
        } else {
            // 企业 ticket
            ticket = WxApiUtils.getJsapiTicketOfCorp(corpId);
        }

        String noncestr = "" + System.currentTimeMillis();
        String timestamp = "" + System.currentTimeMillis();

        String str1 = "jsapi_ticket=" + ticket +
                "&noncestr=" + noncestr +
                "&timestamp=" + timestamp +
                "&url=" + chatToolProperties.getWebUrl() + uriPath;
        String sign = DigestUtils.sha1Hex(str1);

        log.info("str1:{}",str1);
        log.info("sign:{}",sign);

        String wxCorpId = corpService.getCorpInfoById(corpId).getWxCorpId();
        //String wxAgentId = workAgentService.getWxAgentById(agentId);
        String wxAgentId = agentId.toString();

        JsSdkVo vo = new JsSdkVo(wxCorpId,wxCorpId,wxAgentId,noncestr,timestamp,sign);

        return R.ok(vo);
    }

    /**
     * 添加应用
     * @param wxAgentId
     * @param wxSecret
     * @param type
     * @return
     */
    @SysLog("添加应用")
    @PostMapping("/store")
    @ApiOperation(value = "添加应用")
    public ApiRespVO storeAgent(String wxAgentId,String wxSecret,int type) {
        if (!StringUtils.hasLength(wxAgentId)) {
            throw new CheckedException("wxAgentId 不能为空");
        }
        if (!StringUtils.hasLength(wxSecret)) {
            throw new CheckedException("wxSecret 不能为空");
        }

        workAgentService.storeAgent(wxAgentId, wxSecret, type);

        return ApiRespUtils.getApiRespOfOk();
    }

    @GetMapping("/chattool/config")
    public ApiRespVO getChatToolConfig() {
        List<Map<String, Object>> agents = workAgentService.getChatTools();
        if (agents.isEmpty()) {
            return ApiRespUtils.getApiRespOfOk();
        }

        List<String> whiteDomains = new ArrayList<>();
        whiteDomains.add(chatToolProperties.getApiUrl());
        whiteDomains.add(chatToolProperties.getWebUrl());

        Map<String, Object> result = new HashMap<>(2);
        result.put("agents", agents);
        result.put("whiteDomains", whiteDomains);
        return ApiRespUtils.getApiRespOfOk(result);
    }

}
